home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk2 / undel1 / ud1.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  6KB  |  227 lines

  1. /* Undelete.c V1.0: A program to recover deleted files.        
  2.  
  3. This program will scan a disk for the given filename, and copy the file
  4. to another disk if found.  It is NOT case sensitive, and will find all
  5. copies of the file on the disk with the same 
  6. name.
  7.  
  8. When the file is copied, the number of the first block of the file is
  9. appended to the name to keep multiple copies from overwriting each other.
  10.  
  11. author: James Cooper Jr.
  12.     2104B Rogers Dr.
  13.     Fayetteville, NC 28303
  14.  
  15. With thanks to:
  16.     Tom Wilcox
  17.     3047 Cameron Way
  18.     Santa Clara, CA 95051
  19.  
  20. for his fixdisk.c program.  This program is given to the public domain, but
  21. please keep the credits intact. */
  22.  
  23. #include "exec/types.h"
  24. #include "exec/nodes.h"
  25. #include "exec/lists.h"
  26. #include "exec/memory.h"
  27. #include "exec/interrupts.h"
  28. #include "exec/ports.h"
  29. #include "exec/libraries.h"
  30. #include "exec/io.h"
  31. #include "exec/tasks.h"
  32. #include "exec/execbase.h"
  33. #include "exec/devices.h"
  34. #include "ctype.h"
  35. #include "devices/trackdisk.h"
  36. #include "stdio.h"
  37.  
  38. #define TD_READ CMD_READ
  39. #define BLOCKSIZE TD_SECTOR
  40.  
  41. struct MsgPort *diskport;
  42. struct IOExtTD *diskreq;
  43.  
  44. #define NAMELENGTH 408
  45. #define FILENAME   409
  46. #define TypeDATA     8
  47.  
  48. struct DataBlock
  49.    {
  50.     LONG  type, key, seqnum, size, next, checksum;
  51.     UBYTE data[BLOCKSIZE-24];
  52.    } DataBlock, *diskdata;
  53.  
  54. FILE *fopen();
  55.  
  56. int blocks = 0;
  57.  
  58. extern struct MsgPort *CreatePort();
  59. extern struct IORequest *CreateExtIO();
  60.  
  61. ULONG diskChangeCount;
  62.  
  63. /*
  64. #include "devices/extio.h"    I have no such file and Manx compiles
  65.                 just fine without it - John Hiday
  66. */
  67.  
  68. char name[80];
  69.  
  70. long ReadBlock (Block, Kind)
  71.    LONG Block;
  72.    char *Kind;
  73. {
  74.    diskreq->iotd_Req.io_Length = BLOCKSIZE;
  75.    diskreq->iotd_Req.io_Data = (APTR) diskdata;
  76.           
  77.      /* show where to put the data when read */
  78.    diskreq->iotd_Req.io_Command = ETD_READ;
  79.                /* check that disk not changed before reading */
  80.    diskreq->iotd_Count = diskChangeCount;
  81.    diskreq->iotd_Req.io_Offset = BLOCKSIZE*Block;
  82.    DoIO(diskreq);
  83.  
  84.    if (diskreq->iotd_Req.io_Error != 0)
  85.       { 
  86.      printf("*** Can't read %s from block %ld; error %ld\n",
  87.         Kind,Block,diskreq->iotd_Req.io_Error); 
  88.      return (FALSE);
  89.       }
  90.    return (TRUE);
  91. }
  92.  
  93. MotorOn()
  94. {
  95.     /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
  96.     diskreq->iotd_Req.io_Length = 1;  /* 1 => motor is to be turned on */
  97.     diskreq->iotd_Req.io_Command = TD_MOTOR;   /* operate on the motor */
  98.     DoIO(diskreq);
  99. }
  100.  
  101. MotorOff()
  102. {
  103.     diskreq->iotd_Req.io_Length = 0
  104. ; /* 0 => motor is to be turned off */
  105.     diskreq->iotd_Req.io_Command = TD_MOTOR;   /* operate on the motor */
  106.     DoIO(diskreq);
  107. }
  108.  
  109. CopyFile(FirstBlock)
  110.    LONG FirstBlock;
  111. {
  112.    FILE *file;
  113.    LONG block = FirstBlock;
  114.  
  115.    printf ("\n\n");
  116.  
  117.    sprintf (name, "DF1:%s.%ld", &DataBlock.data [FILENAME], block);
  118.    printf ("Writing file %s\n", name);
  119.  
  120.    if ((file = fopen (name, "w")) == NULL)
  121.    {
  122.        printf ("Cannot open %s\n\n", name);
  123.        return (0);
  124.    }
  125.  
  126.    for (block = FirstBlock; block != 0; block = DataBlock.next)
  127.    { 
  128.      if (!ReadBlock (block, "file data")) break;     
  129.  
  130.      if (fwrite (DataBlock.data, DataBlock.size, 1, file) != 1)
  131.         printf ("*** Can't write data block %ld from disk block %ld\n",
  132.         DataBlock.seqnum, block);
  133.      
  134.      blocks = blocks-1;
  135.    }
  136.  
  137.    if (block==0) { printf ("File %s is complete\n\n", name); }
  138.    else printf ("File %s has been truncated\n\n", name);
  139.  
  140.    fclose (file);
  141. }
  142.  
  143. StrComp(str1, str2)
  144. char *str1, *str2;
  145. {
  146.    int index = 0;
  147.  
  148.    while (1)
  149.    {
  150.       if (str1[index] == 0 && str2[index] == 0) return(0);
  151.       if (toupper(str1[index]) != toupper(str2[index])) return(-1);
  152.       index++;
  153.    }
  154. }
  155.  
  156. main(argc, argv)
  157. int argc;
  158. char **argv;   
  159. {
  160.    LONG block;
  161.    char *lookedfor;
  162.  
  163.    if (argc == 1)
  164.    {
  165.       printf("Usage: Undelete <filename>\n\n");
  166.       exit(0);
  167.    }
  168.  
  169.    lookedfor = argv[1];
  170.  
  171.    diskdata = &DataBlock;       /* point to first location in disk buffer */
  172.    if ((diskport = CreatePort(0,0)) == 0) exit(100);    /* error */
  173.  
  174.    /* make an io request block for communicating with the disk */
  175.    diskreq = (struct IOExtTD *)CreateExtIO(diskport,sizeof(struct IOExtTD));
  176.  
  177.    if(diskreq == 0) { DeletePort(diskport); exit(200); }
  178.  
  179.    /* open the device for access, unit 0 is builtin drive */
  180.    if (0 != OpenDevice(TD_NAME,0,diskreq,0)) exit (150);
  181.  
  182.    printf ("Put disk with deleted file in INTERNAL drive.\n");
  183.    printf ("(Cancel the requester if the disk is unreadable.)\n");
  184.    printf ("Put empty disk in EXTERNAL drive.\n");
  185.    printf ("Press RETURN to begin.\n")
  186. ;
  187.  
  188.    getchar();
  189.  
  190.    /* now get the disk change value */
  191.    diskreq->iotd_Req.io_Command = TD_CHANGENUM;
  192.    DoIO(diskreq);
  193.    diskChangeCount = diskreq->iotd_Req.io_Actual;
  194.  
  195.    printf ("Scanning disk for %s...\n", lookedfor);
  196.  
  197.    for (block = 0; block < 1760; block++)
  198.    {
  199.       if (ReadBlock (block, "information") && DataBlock.type == TypeDATA)
  200.       {
  201.          blocks += 1;
  202.       
  203.    if (DataBlock.seqnum == 1)
  204.      {
  205.         if (ReadBlock(DataBlock.key, "file header"))
  206.         {
  207.            DataBlock.data [FILENAME + DataBlock.data [NAMELENGTH]] = 0;
  208.            sprintf (name, "%s", &DataBlock.data [FILENAME]);
  209.         }
  210.         else
  211.            name[1] = 0;
  212.  
  213.         printf ("Name = %s%cK\r", name, 0x9b);
  214.         if (StrComp(name, lookedfor) == 0) CopyFile (block);
  215.      }
  216.       }
  217.    }
  218.  
  219.    printf ("\n\nAll disk blocks have been scanned.\n");
  220.    MotorOff();
  221.    CloseDevice(diskreq);
  222.    DeleteExtIO(diskreq, sizeof(struct IOExtTD));
  223.    DeletePort(diskport);
  224.    exit(0);
  225. }
  226.  
  227.